package com.heartrate.tool;

import java.util.Arrays;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.heartrate.R;
import com.heartrate.tool.graphs.CallbackRingView;

/**
 * 心率动画类
 */
public class RingView extends View {

    /**
     * 整个View的宽高
     * */
    private int mTotalHeight, mTotalWidth;

    /**
     * 心跳线的总宽度 -- 圆环的宽度
     * */
    private int mHeartBeatWidth;

    /**
     * 圆环半径 根据view的宽度计算
     * */
    private int mRadius = 200;

    /**
     * 圆环的中心点 -- 画圆环和旋转画布时需要使用
     * */
    private int x, y;

    /**
     * 圆环使用
     * */
    private Paint mRingPaint;

    /**
     * 圆环动画使用 -- 与mRingPaint唯一不同得方在于颜色
     * */
    private Paint mRingAnimPaint;

    /**
     * 圆环大小 矩形
     * */
    private RectF mRectf;

    private Context mContext;

    /**
     * 圆环 宽度
     * */
    private final int mHeartPaintWidth = 50;

    /**
     * 圆环动画开始时 画弧的偏移量
     * */
    private int mAnimAngle = -1;

    /**
     * 心跳线 Y轴坐标
     * */
    private float[] mOriginalYPositon;

    /**
     * 心跳线 Y轴坐标 -- 默认坐标
     * */
    private float [] mDefaultYPostion;

    // y = Asin(w*x)+Y
    /**
     * sin函数 周期因子
     * */
    private float mPeriodFraction = 0;

    /**
     * 期初的偏移量
     * */
    private final int OFFSET_Y = 0;

    /**
     * canvas抗锯齿开启需要
     * */
    private DrawFilter mDrawFilter;

    /**
     * 正弦曲线偏移量
     * */
    private volatile int mOffset= 0;

    /**
     * 振幅
     * */
    private float AmplitudeA = 200;// 振幅

    /**
     * 心跳线条速度
     * */
    private final int SPEED = 5;

    /**
     * 将SPEED转换为实际速度
     * */
    private int mOffsetSpeed;

    /**
     * 绘制心率线Paint
     * */
    private Paint mHeartBeatPaint;

    /**
     * 绘制心率线path的Paint -- 优化
     * */
    private Paint mHeartBeatPathPaint;

    Path path = new Path();

    public void init() {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        //设圆环画笔Paint
        mRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        if (!isInEditMode()) {
            // 造成错误的代码段
            mRingPaint.setColor(mContext.getResources().getColor(R.color.heart_default));
        }
        mRingPaint.setStrokeWidth(mHeartPaintWidth);//圆环 宽度 = 50
        mRingPaint.setStyle(Style.STROKE);//空心
        mRingAnimPaint = new Paint(mRingPaint);
        mRingAnimPaint.setColor(Color.WHITE);

        //初始化心跳曲线
        mDrawFilter = new PaintFlagsDrawFilter  //在画图的时候，图片如果旋转或缩放之后，总是会出现那些华丽的锯齿
                (0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);//canvas抗锯齿开启需要
        mOffsetSpeed = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, SPEED, //将SPEED转换为实际速度
                mContext.getResources().getDisplayMetrics());
        mHeartBeatPaint  =new Paint(Paint.ANTI_ALIAS_FLAG);
        mHeartBeatPaint.setStrokeWidth(5);//设置曲线宽度
        //mHeartBeatPaint.setStyle(Style.STROKE);

        if (!isInEditMode()) { //使用isInEditMode解决可视化编辑器无法识别自定义控件的问题
            mHeartBeatPaint.setColor(mContext.getResources().getColor(R.color.heartbeat));
        }
        //优化心率线
        mHeartBeatPathPaint = new Paint(mHeartBeatPaint);
        mHeartBeatPathPaint.setStrokeWidth(5);
        mHeartBeatPathPaint.setStyle(Style.STROKE);
    }

    /**
     * View 大小改变是被调用
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mTotalHeight = h;//总高
        mTotalWidth = w;//总宽
        mHeartBeatWidth = w - mHeartPaintWidth*2-40; //内圆宽度
        mFirstFrameOffset = mHeartBeatWidth - 1;
        AmplitudeA = (mTotalHeight-2*mHeartPaintWidth)/4;//振幅
        mOriginalYPositon = new float[mHeartBeatWidth];//正弦曲线 Y坐标 心跳线
        mDefaultYPostion = new float[mHeartBeatWidth];//心跳线 Y轴坐标 -- 默认坐标
        Arrays.fill(mOriginalYPositon, 0);//为mOriginalYPositon 添加一个0元素
        Arrays.fill(mDefaultYPostion, -1);//为mOriginalYPositon 添加一个0元素

        // 周期定位总宽度的1/4
        mPeriodFraction = (float) (Math.PI * 2 / mHeartBeatWidth * 3);//sin函数 周期因子
        for (int i =  mHeartBeatWidth/3*2; i < mHeartBeatWidth; i++) {
            //心跳线设值及三角函数  y = A*sin(wx+t) w为函数周期因子
            mOriginalYPositon[i] = (float) (AmplitudeA * Math.sin(mPeriodFraction * i) + OFFSET_Y);//OFFSET_Y=0期初的偏移量
        }
        x = w / 2;
        y = h / 2;
        mRadius = w / 2 - mHeartPaintWidth / 2; //圆环半径 根据view的宽度计算,因为制定了Paint的宽度，因此计算半径需要减去这个
        mRectf = new RectF(x - mRadius, y - mRadius, x + mRadius, y + mRadius);//圆环大小 矩形
    }

    /**
     * 优化路径，效果差
     */
    private void resetPath(){
        path.reset();
        path.moveTo(mHeartPaintWidth+20, mTotalHeight/2-mOriginalYPositon[mOffset]);
        int interval = mHeartBeatWidth - mOffset;
        for(int i=mOffset+1,j=mHeartPaintWidth+20;i<mHeartBeatWidth;i++,j++){
            path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
        }
        for(int i=0,j=interval+mHeartPaintWidth+20;i<mOffset;i++,j++){
            path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
        }

    }

    /**
     * 优化路径，效果好
     */
    private void resetPath1(){
        path.reset();
        path.moveTo(mHeartPaintWidth+20, mTotalHeight/2-mOriginalYPositon[mOffset]);
        int interval = mHeartBeatWidth - mOffset;
        //先找到全0的部分
        int index = -1;
        for(int i=mOffset+1;i<mHeartBeatWidth;i++){
            if(mOriginalYPositon[i]==0){
                index = i;
            }else{
                break;
            }
        }
        if(index!=-1){
            path.lineTo(mHeartPaintWidth+20+(index-mOffset+1), mTotalHeight/2);
            for(int i=index+1,j=mHeartPaintWidth+20+(index-mOffset+2);i<mHeartBeatWidth;i++,j++){
                path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
            }
        }else{
            for(int i=mOffset+1,j=mHeartPaintWidth+20;i<mHeartBeatWidth;i++,j++)
                path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
        }
        //查找最后全为0的index
        index = -1;
        for(int i =0;i<mOffset;i++){
            if(mOriginalYPositon[i]==0)
                index = i;
            else
                break;
        }
        if(index !=-1){
            //修正视觉偏移量
            path.lineTo(mHeartPaintWidth+20+(mHeartBeatWidth-mOffset), mTotalHeight/2);
            path.lineTo(interval+mHeartPaintWidth+20+index, mTotalHeight/2);
            for(int i=index+1,j=interval+mHeartPaintWidth+20+index+1;i<mOffset;i++,j++){
                path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
            }
        }else{
            for(int i=0,j=interval+mHeartPaintWidth+20;i<mOffset;i++,j++)
                path.lineTo(j, mTotalHeight/2-mOriginalYPositon[i]);
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.setDrawFilter(mDrawFilter);//在canvas上抗锯齿
        //由于drawArc默认从x轴开始画，因此需要将画布旋转或者绘制角度旋转，2种方案
        //int level = canvas.save();
        //canvas.rotate(-90, x, y);// 旋转的时候一定要指明中心
        //圆环背景图
        for (int i = 0; i < 360; i += 3) {
//            oval :指定圆弧的外轮廓矩形区域。
//            startAngle: 圆弧起始角度，单位为度。
//            sweepAngle: 圆弧扫过的角度，顺时针方向，单位为度,从右中间开始为零度。
//            useCenter: 如果为True时，在绘制圆弧时将圆心包括在内，通常用来绘制扇形。
//            paint: 绘制圆弧的画板属性，如颜色，是否填充等。
            canvas.drawArc(mRectf, i, 1, false, mRingPaint);
        }
        if (mAnimAngle != -1) {// 如果开启了动画,圆环动画开始时 画弧的偏移量 = -1
            for (int i = -90; i < mAnimAngle-90; i += 3) {
                canvas.drawArc(mRectf, i, 1, false, mRingAnimPaint);
            }
        }

        //canvas.restoreToCount(level);
        if(StartHeartBeatAnmiFlag){
            resetPath1(); //或者resetPath ，这个优化效果一般
            canvas.drawPath(path, mHeartBeatPathPaint);
            canvas.drawCircle(mHeartBeatWidth+20+mHeartPaintWidth, mTotalHeight/2-mOriginalYPositon[mOffset], 10, mHeartBeatPaint);
        }
        if(StartFirstFrameFlag){
            for(int i=0,j=mHeartPaintWidth+20;i<mHeartBeatWidth;i++,j++){
                if(mDefaultYPostion[i]==-1)
                    continue;
                else
                    canvas.drawPoint(j, mTotalHeight/2-mDefaultYPostion[i], mHeartBeatPaint);
            }
        }
		/*-------------通过drawPoint方法绘制 会降低性能--------------------*/
	/*	if(StartHeartBeatAnmiFlag){
			//绘制心跳线
			int interval = mHeartBeatWidth - mOffset;
			for(int i=mOffset,j=mHeartPaintWidth+20;i<mHeartBeatWidth;i++,j++){
				canvas.drawPoint(j, mTotalHeight/2-mOriginalYPositon[i], mHeartBeatPaint);
			}
			for(int i=0,j=interval+mHeartPaintWidth+20;i<mOffset;i++,j++){
				canvas.drawPoint(j, mTotalHeight/2-mOriginalYPositon[i], mHeartBeatPaint);
			}
			canvas.drawCircle(mHeartBeatWidth+20+mHeartPaintWidth, mTotalHeight/2-mOriginalYPositon[mOffset], 10, mHeartBeatPaint);
		}*/
    }

    /*---------------------------------动画 start -----------------------------------------*/
    private volatile boolean StartHeartBeatAnmiFlag = false;

    private volatile boolean StartFirstFrameFlag = false;

    private   int mFirstFrameOffset = 0;

    private Thread firstFrame;
    /**
     * 开启心跳曲线动画
     * */
    private void startHeartBeatAnmi(){
        firstFrame = new Thread(new Runnable() {
            @Override
            public void run() {
                StartFirstFrameFlag = true;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                System.out.println(mOriginalYPositon.length);
                System.out.println(mDefaultYPostion.length);
                //mFirstFrameOffset = 384;
                System.out.println(mFirstFrameOffset);
                System.out.println(mOriginalYPositon.length - mFirstFrameOffset);
                //mOriginalYPositon.length - mFirstFrameOffset = 0;
                while (mFirstFrameOffset > 0) {
                   System.arraycopy(mOriginalYPositon,0,mDefaultYPostion, mFirstFrameOffset,mOriginalYPositon.length - mFirstFrameOffset );
                   // System.arraycopy(mOriginalYPositon,0,mDefaultYPostion, 384,0 );
                    mFirstFrameOffset--;
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {

                    }
                    postInvalidate();
                }
                StartFirstFrameFlag = false;
                StartHeartBeatAnmiFlag = true;
                startSecondFrameAnmi();
            }
        });
        firstFrame.start();
    }
    private Thread secondFrame;
    /**
     * 心率第二段曲线图
     * */
    private void startSecondFrameAnmi(){

        secondFrame = new Thread(new Runnable() {
            @Override
            public void run() {
                while (StartHeartBeatAnmiFlag) {
                    mOffset += mOffsetSpeed;
                    if(mOffset>=mHeartBeatWidth)
                        mOffset = 0;
                    try {
                        Thread.sleep(60);
                    } catch (InterruptedException e) {
                    }
                    postInvalidate();
                }
            }
        });
        secondFrame.start();
    }

    /**
     * 开启圆环动画
     * */
    private void startRingAnim(final CallbackRingView callbackRingView) {
        mAnimAngle = 0;
        Thread ringThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (mAnimAngle < 360) {
                    mAnimAngle++;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    postInvalidate();
                }
                mAnimAngle = -1;// 停止动画
                stopAnim(callbackRingView);
            }
        });
        ringThread.start();
    }

    public void stopAnim(CallbackRingView callbackRingView){
        //StartFirstFrameFlag = false;
        mOriginalYPositon = null;
        mDefaultYPostion = null;
        onSizeChanged_(525,525,0,0);
        StartHeartBeatAnmiFlag = false;
        callbackRingView.success("success");
    }
    protected void onSizeChanged_(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mTotalHeight = h;//总高
        mTotalWidth = w;//总宽
        mHeartBeatWidth = w - mHeartPaintWidth*2-40; //内圆宽度
        mFirstFrameOffset = mHeartBeatWidth - 1;
        AmplitudeA = (mTotalHeight-2*mHeartPaintWidth)/4;//振幅
        mOriginalYPositon = new float[mHeartBeatWidth];//正弦曲线 Y坐标 心跳线
        mDefaultYPostion = new float[mHeartBeatWidth];//心跳线 Y轴坐标 -- 默认坐标
        Arrays.fill(mOriginalYPositon, 0);//为mOriginalYPositon 添加一个0元素
        Arrays.fill(mDefaultYPostion, -1);//为mOriginalYPositon 添加一个0元素

        // 周期定位总宽度的1/4
        mPeriodFraction = (float) (Math.PI * 2 / mHeartBeatWidth * 3);//sin函数 周期因子
        for (int i =  mHeartBeatWidth/3*2; i < mHeartBeatWidth; i++) {
            //心跳线设值及三角函数  y = A*sin(wx+t) w为函数周期因子
            mOriginalYPositon[i] = (float) (AmplitudeA * Math.sin(mPeriodFraction * i) + OFFSET_Y);//OFFSET_Y=0期初的偏移量
        }
        x = w / 2;
        y = h / 2;
        mRadius = w / 2 - mHeartPaintWidth / 2; //圆环半径 根据view的宽度计算,因为制定了Paint的宽度，因此计算半径需要减去这个
        mRectf = new RectF(x - mRadius, y - mRadius, x + mRadius, y + mRadius);//圆环大小 矩形
    }
    public void startAnim(CallbackRingView callbackRingView){
        startHeartBeatAnmi();//心跳折线图
        startRingAnim(callbackRingView);//圆环动画

    }

	/*---------------------------------动画  end------------------------------------*/

    /*---------------------------------构造函数-----------------------------------*/
    public RingView(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public RingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }

    public RingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        init();
    }

}
